﻿#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QDataStream>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),
    m_p1IsReady(false),
    m_p2IsReady(false),
    m_isInit(false)
{
    ui->setupUi(this);
    init();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::init()
{
    m_tcpServer = new QTcpServer(this);
    consoleColor(QColor(Qt::black), "正在加载中...\n\n");

    // 监听端口
    if(!m_tcpServer->listen(QHostAddress::Any, 8808)){
        QString strError = m_tcpServer->errorString();
        ui->Console->appendPlainText(strError);
    }

    connect(m_tcpServer, &QTcpServer::newConnection, this, &Widget::newCon);
}

void Widget::consoleColor(QColor color, QString str)
{
    QTextCursor cursor = ui->Console->textCursor();
    QTextCharFormat format;
    format.setForeground(QBrush(color));
    cursor.mergeCharFormat(format);
    cursor.insertText(str);
}

void Widget::tcpBack(QByteArray bt, QTcpSocket* tempSocket)
{
    QByteArray btPack;
    QDataStream out(&btPack, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_0); // 设置版本，保证跨平台兼容性
    out << quint32(0);

    quint32 btSize = bt.size() + sizeof(quint32);

    out << bt;
    btPack.remove(0, sizeof(quint32));
    out.device()->seek(0);
    out << btSize;

    int res = tempSocket->write(btPack);
}

void Widget::newCon()
{
    QTcpSocket* tempSocket = m_tcpServer->nextPendingConnection();

    QString strRead = "IP(" + tempSocket->peerAddress().toString();
    strRead += ") 端口(" + QString::number(tempSocket->peerPort()) + ")";
    if(ui->label_p1->text() == "无人连接"){
        QPalette palette = ui->label_p1->palette();
        palette.setColor(QPalette::WindowText, QColor(85, 170, 39));
        ui->label_p1->setPalette(palette);
        ui->label_p1->setText(strRead);
        m_tcpSocket_p1 = tempSocket;
        m_IP_p1 = QString::number(tempSocket->peerPort());
        m_p1IsReady = true;
    }else if(ui->label_p2->text() == "无人连接"){
        QPalette palette = ui->label_p2->palette();
        palette.setColor(QPalette::WindowText, QColor(85, 170, 39));
        ui->label_p2->setPalette(palette);
        ui->label_p2->setText(strRead);
        m_tcpSocket_p2 = tempSocket;
        m_IP_p2 = QString::number(tempSocket->peerPort());
        m_p2IsReady = true;
    }else{
        strRead += "的客户端连接失败(连接槽已满)\n\n";
        consoleColor(QColor(Qt::red), strRead);
        return;
    }

    connect(tempSocket, &QTcpSocket::disconnected, [this, tempSocket, strRead]{
        refuseBack(tempSocket);
    });
    connect(tempSocket, &QTcpSocket::readyRead, [this, tempSocket](){
        tcpInfoHanle(tempSocket);
    });

    strRead += "的客户端连接成功\n";
    consoleColor(QColor(Qt::blue), strRead);
    msgBack(tempSocket);

    if(m_p1IsReady && m_p2IsReady){
        gameStart();
    }
}

void Widget::msgBack(QTcpSocket* tempSocket)
{
    QString str = "555";
    //tempSocket->write(str.toUtf8());
    tcpBack(str.toUtf8(), tempSocket);

    QString strRead = "IP(" + tempSocket->peerAddress().toString();
    strRead += ") 端口(" + QString::number(tempSocket->peerPort()) + ")";
    consoleColor(QColor(Qt::blue), "已向" + strRead + "的客户端回信\n\n");
}

void Widget::refuseBack(QTcpSocket *tempSocket)
{
    QString strRead = "IP(" + tempSocket->peerAddress().toString();
    strRead += ") 端口(" + QString::number(tempSocket->peerPort()) + ")";
    consoleColor(QColor(Qt::red), strRead + "的客户端断开连接\n\n");
    tempSocket->deleteLater();
    if(tempSocket == m_tcpSocket_p1){
        QPalette palette = ui->label_p1->palette();
        palette.setColor(QPalette::WindowText, QColor(Qt::black));
        ui->label_p1->setPalette(palette);
        ui->label_p1->setText("无人连接");
        m_p1IsReady = false;
    }else if(tempSocket == m_tcpSocket_p2){
        QPalette palette = ui->label_p2->palette();
        palette.setColor(QPalette::WindowText, QColor(Qt::black));
        ui->label_p2->setPalette(palette);
        ui->label_p2->setText("无人连接");
        m_p2IsReady = false;
    }

    m_isInit = false;
}

void Widget::tcpInfoHanle(QTcpSocket* tempSocket)
{
    if(!m_p1IsReady || !m_p2IsReady){
        return;
    }

    while(tempSocket->bytesAvailable() >= sizeof(quint32)){
        QByteArray bt;
        QDataStream in(tempSocket);
        in.setVersion(QDataStream::Qt_5_0);

        // 读取数据大小
        quint32 btSize;
        in >> btSize;
        if(tempSocket->bytesAvailable() < btSize - sizeof(quint32)){
            break;
        }

        bt.resize(btSize - sizeof(quint32));
        in.readRawData(bt.data(), bt.size());

        QString tempStr = QString::fromUtf8(bt);
        tcpInfoUse(tempSocket, tempStr);
    }




}

void Widget::tcpInfoUse(QTcpSocket* tempSocket, QString tempStr)
{
    QString strRead = "IP(" + tempSocket->peerAddress().toString();
    strRead += ") 端口(" + QString::number(tempSocket->peerPort()) + ")";
    if(strRead == ui->label_p1->text()){
        strRead = "玩家1发来信息: " + tempStr + "\n\n";
    }else if(strRead == ui->label_p2->text()){
        strRead = "玩家2发来信息: " + tempStr + "\n\n";
    }
    consoleColor(QColor(Qt::blue), strRead);

    if(tempStr.at(0) == "9" && m_isInit == false){ // 表示初始化
        m_isInit = true;
        if(QString::number(tempSocket->peerPort()) == m_IP_p1){
            tcpBack(tempStr.toUtf8(), m_tcpSocket_p2);
            consoleColor(QColor(Qt::blue), "已向玩家2发送初始化信息\n\n");
        }else{
            tcpBack(tempStr.toUtf8(), m_tcpSocket_p1);
            consoleColor(QColor(Qt::blue), "已向玩家1发送初始化信息\n\n");
        }
    }else if(tempStr.at(0) == "7"){ // 表示卡牌操作信息
        if(QString::number(tempSocket->peerPort()) == m_IP_p1){
            tcpBack(tempStr.toUtf8(), m_tcpSocket_p2);
            consoleColor(QColor(Qt::blue), "已向玩家2发送玩家1操作信息\n\n");
        }else{
            tcpBack(tempStr.toUtf8(), m_tcpSocket_p1);
            consoleColor(QColor(Qt::blue), "已向玩家1发送玩家2操作信息\n\n");
        }
    }

}

void Widget::gameStart()
{
    consoleColor(QColor(Qt::cyan), "客户端数量已满, 开始准备\n\n");
    QString str = "888";
//    m_tcpSocket_p1->write(str.toUtf8());
//    m_tcpSocket_p2->write(str.toUtf8());
    tcpBack(str.toUtf8(), m_tcpSocket_p1);
    tcpBack(str.toUtf8(), m_tcpSocket_p2);
}

void Widget::on_pushButton_clicked()
{
    ui->Console->clear();
}
